package org.example.mvc;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class InputStreamHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private final byte[] streamBody;
    private static final int BUFFER_SIZE = 4096;

    public InputStreamHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        // 读取流得到字节数组
        byte[] bytes = inputStreamToByteArray(request.getInputStream());
        streamBody = bytes;
    }

    /**
     * 读取输入流, 读到字节数组输出流获取字节数组
     *
     * @param inputStream
     * @return byte[]
     * @author: ZhiHao
     * @date: 2021/1/21
     */
    private byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[BUFFER_SIZE];
        int length;
        while ((length = inputStream.read(bytes, 0, BUFFER_SIZE)) != -1) {
            outputStream.write(bytes, 0, length);
        }
        return outputStream.toByteArray();
    }

    /**
     * 重写获取流方法, 使用自定义ByteArrayInputStream, 便于多次读取
     * 每次调用getInputStream方法，其实是重新利用streamBody重新new一个流，所以可以多次读取
     *
     * @return ServletInputStream
     * @author: ZhiHao
     * @date: 2021/1/21
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(streamBody);

        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }

            @Override
            public int read() throws IOException {
                return inputStream.read();
            }
        };
    }

    /**
     * 重写获取读流方法, 便于多次读取
     *
     * @return java.io.BufferedReader
     * @author: ZhiHao
     * @date: 2021/1/21
     */
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
}
